﻿// Inner Fire 游戏引擎库
// 材质类
//
// Copyright (c) 2024 by 尔西大帝. All rights reserved.
//
// 用于材质
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-12-01

#include "dx_material.h"
#include <xml_reader.h>
#include <game/core/timer.h>

using namespace ikit;

namespace ifire::dx {
Material::Material(int index, const MaterialDesc& desc)
    : DxElement(index, desc.name)
    , albedo(desc.albedo)
    , normal(desc.normal)
    , tint(desc.tint)
    , fresnel_r0(desc.fresnel_r0)
    , roughness(desc.roughness) {}

void Material::Update(UploadBuffer<MaterialData>* buffer) {
  if (frame_dirty_count == 0) {
    return;
  }

  XMMATRIX matTransform = XMLoadFloat4x4(&mat_transform);

  // 这里使用MaterialData
  MaterialData matData;
  matData.DiffuseAlbedo = tint;
  matData.FresnelR0 = fresnel_r0;
  matData.Roughness = roughness;
  XMStoreFloat4x4(&matData.MatTransform, XMMatrixTranspose(matTransform));
  matData.DiffuseMapIndex = diffuse_index;

  // 需要复制到cb_index指针的位置
  buffer->CopyData(Index(), matData);

  // 其它的帧同样也要更新
  frame_dirty_count--;
}


void Material::AnimateWaterMaterials() {
  // Scroll the water material texture coordinates.

  float& tu = mat_transform(3, 0);
  float& tv = mat_transform(3, 1);

  tu += 0.1f * game::g_timer.fixedDeltaTime;
  tv += 0.02f * game::g_timer.fixedDeltaTime;

  if (tu >= 1.0f)
    tu -= 1.0f;

  if (tv >= 1.0f)
    tv -= 1.0f;

  mat_transform(3, 0) = tu;
  mat_transform(3, 1) = tv;

  // Material has changed, so need to update cbuffer.  
  frame_dirty_count = FRAME_RESOURCE_COUNT;
}

} // namespace ifire::dx
